using System;
using System.IO;
using System.Xml.Serialization;
using AzureContrib.WindowsAzure.Utils;
using Microsoft.WindowsAzure.StorageClient;

namespace AzureContrib.WindowsAzure.StorageClient
{
	/// <summary>
	/// Extensions on <see cref="CloudQueueMessage"/> using xml
	/// </summary>
	public static class CloudQueueExtensionsXml
	{
		/// <summary>
		/// Deserialize a <see cref="CloudQueueMessage"/> to an instance of the given type <typeparamref name="T"/>.
		/// </summary>
		/// <typeparam name="T">The type of oject the message is serialized from.</typeparam>
		/// <param name="cloudQueueMessage">The actual message on the queue.</param>
		/// <returns>An instance of type <typeparamref name="T"/></returns>
		public static T PayloadXml<T>(this CloudQueueMessage cloudQueueMessage)
		{
			var serializer = new XmlSerializer(typeof(T));
			var stream = new MemoryStream(cloudQueueMessage.AsBytes);
			var t = (T)serializer.Deserialize(stream);
			return t;
		}

		/// <summary>
		/// Serialize a <see cref="CloudQueueMessage"/> form an instance.
		/// </summary>
		/// <param name="instance">The actual message on the queue.</param>
		/// <returns>A <see cref="CloudQueueMessage"/> serialized from the data in the <paramref name="instance"/></returns>
		public static CloudQueueMessage ToCloudQueueMessageXml<T>(this T instance) where T : class
		{
			var serializer = new XmlSerializer(instance.GetType());
			var memoryStream = new MemoryStream();
			serializer.Serialize(memoryStream, instance);

			if (memoryStream.Length > CloudQueueMessageExtensions.MaxMessageBuffer)
			{
				throw new ArgumentException("The message to serialize is greater than 8Kb. Type: {0}, .ToString(): {1}".F(instance.GetType().FullName, instance));
			}

			byte[] byteArray = new byte[memoryStream.Length];
			memoryStream.Position = 0;
			memoryStream.Read(byteArray, 0, (int)memoryStream.Length);

			return new CloudQueueMessage(byteArray);
		}
	}
}